package edu.caltech.android;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

import edu.caltech.android.c2dm.HelpActivity;
import edu.caltech.android.c2dm.Prefs;
import edu.caltech.android.c2dm.SetupActivity;
import edu.caltech.android.picking.Pick;
import edu.caltech.android.waveforms.WaveformDisplay;

/**
 * Displays a shake map.
 * 
 * Info on MapActivity:
 * http://code.google.com/intl/ja/android/add-ons/google-apis/maps-overview.html
 * 
 * how to draw things on the map. Related classes: MapOverlay, ItemizedOverlay
 * see http://eagle.phys.utk.edu/guidry/android/mapOverlayDemo.html
 * 
 * TODO: broadcast receivers should be configured in the AndroidManifest, to
 * remove the need to dynamically register / unregister
 * 
 * @author mfaulk
 * 
 */
public class ShakeAlertActivity extends MapActivity {
	@SuppressWarnings("unused")
	private static final String TAG = "ShakeAlert";
	private static final int WAVEFORMS_ID = Menu.FIRST;
	private static final int INFO_ID = Menu.FIRST + 1;
	private static final int QUIT_ID = Menu.FIRST + 2;

	private MapView mapView;
	private MapController mapController;
	private MyLocationOverlay myLocationOverlay;
	private Cursor earthquakeCursor;

	EarthquakeReceiver earthquakeReceiver;
	private PickBroadcastReceiver pickBroadcastReceiver;

	public class EarthquakeReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			earthquakeCursor.requery();
			MapView earthquakeMap = (MapView) findViewById(R.id.mapView);
			earthquakeMap.invalidate();
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Run the C2DM setup first if necessary
		SharedPreferences prefs = Prefs.get(this);
		if (prefs.getString("deviceRegistrationID", null) == null) {
			startActivity(new Intent(this, SetupActivity.class));
		}

		setContentView(R.layout.shake_map2);

		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);

		// set default zoom level

		mapController = mapView.getController();

		// ----- USGS quakes ----- //
		refreshEarthquakes();

		Uri earthquakeURI = EarthquakeProvider.CONTENT_URI;
		earthquakeCursor = getContentResolver().query(earthquakeURI, null,
				null, null, null);
		// let Android manage this cursor for us
		startManagingCursor(earthquakeCursor);
		Drawable quakeMarker = getResources().getDrawable(R.drawable.reddot);
		EarthquakeItemizedOverlay eo = new EarthquakeItemizedOverlay(
				quakeMarker, earthquakeCursor, getApplicationContext());
		mapView.getOverlays().add(eo);

		// ----- client's location ----- //
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		// add client's position

		myLocationOverlay.runOnFirstFix(new Runnable() {
			public void run() {
				mapController.animateTo(myLocationOverlay.getMyLocation());
				mapController.setZoom(10);
			}
		});
		mapView.getOverlays().add(myLocationOverlay);

		mapView.postInvalidate();

		// start main service
		Intent myIntent = new Intent(ShakeAlertActivity.this,
				ShakeAlertService.class);
		startService(myIntent);

		// ---- register for pick broadcasts ---- //
		IntentFilter filter = new IntentFilter(ShakeAlertService.PICK);
		pickBroadcastReceiver = new PickBroadcastReceiver();
		registerReceiver(pickBroadcastReceiver, filter);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		boolean retVal = super.onCreateOptionsMenu(menu);

		// TODO: this should inflate an XML layout in res/menu
		menu.add(0, ShakeAlertActivity.WAVEFORMS_ID, 0, "Accelerometer");
		menu.add(0, ShakeAlertActivity.INFO_ID, 0, "About");
		menu.add(0, ShakeAlertActivity.QUIT_ID, 0, "Quit");

		return retVal;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case INFO_ID:
			// Intent infoIntent = new Intent(ShakeAlertActivity.this,
			// ClientInfo.class);
			// startActivity(infoIntent);
			// finish();
			startActivity(new Intent(this, HelpActivity.class));
			break;
		case WAVEFORMS_ID:
			Intent waveformIntent = new Intent(ShakeAlertActivity.this,
					WaveformDisplay.class);
			startActivity(waveformIntent);
			finish();
			break;
		case QUIT_ID:
			stopService(new Intent(ShakeAlertActivity.this,
					ShakeAlertService.class));
			stopService(new Intent(ShakeAlertActivity.this,
					EarthquakeService.class));
			finish();
			break;
		default:
			//Log.d(TAG, "ShakeAlert:invalid menu item ID");
			break;
		}

		return super.onMenuItemSelected(featureId, item);
	}

	@Override
	public void onPause() {
		earthquakeCursor.deactivate();
		unregisterReceiver(earthquakeReceiver);
		unregisterReceiver(pickBroadcastReceiver);
		super.onPause();
	}

	@Override
	public void onResume() {
		super.onResume();

		earthquakeCursor.requery();
		IntentFilter filter;
		filter = new IntentFilter(EarthquakeService.NEW_EARTHQUAKE_FOUND);
		earthquakeReceiver = new EarthquakeReceiver();
		registerReceiver(earthquakeReceiver, filter);

		// ---- register for pick broadcasts ---- //
		IntentFilter pickFilter = new IntentFilter(ShakeAlertService.PICK);
		pickBroadcastReceiver = new PickBroadcastReceiver();
		registerReceiver(pickBroadcastReceiver, pickFilter);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// TODO: stop the EarthquakeService?
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.google.android.maps.MapActivity#isRouteDisplayed()
	 */
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	private void refreshEarthquakes() {
		startService(new Intent(this, EarthquakeService.class));
	}

	/**
	 * receive Pick broadcasts
	 */
	private class PickBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {

			if (intent.getAction().equals(ShakeAlertService.PICK)) {

				Pick p = intent.getParcelableExtra(ShakeAlertService.PICK_KEY);

				// only display toast if this activity is visible
				// hasWindowFocus sort of checks if this window is visible
				if (p != null && hasWindowFocus()) {
					Toast toast = Toast.makeText(getApplicationContext(),
							"Pick", Toast.LENGTH_SHORT);
					toast.show();
				}

			}
		}
	} // end of class

}